/**
 * 
 */
package org.isaaclabs.mymdb;

import java.io.File;
import java.io.IOException;

import org.apache.http.client.ClientProtocolException;
import org.json.JSONException;

/**
 * Takes care of finding and renaming movie folders and files
 * @author hemanth.sunkara
 * @version $Revision: 1.0 $
 */
public class MovieUtils {

    /**
     * The number of info file fields in the filename 
     */
    private static final int FILENAME_FILD_COUNT = 3;
    /**
     * Files with these extensions will be processed if not found with a folder
     * in the base directory
     */
    private static String[] movieExtensions = {".avi",".divx",".flv",".m4v",".mkv",
        ".mov",".mp4",".mpeg",".mpg",".rm",".vob",".wmv",".xvid"};

    private static String[] junkStrings = {"[","(","dvdrip","xvid"};

    /**
     * Method main.
     * @param args String[]
     * @throws ClientProtocolException  
     * @throws IOException  
     */
    public static void main(String[] args) 
    throws ClientProtocolException, IOException {
        StatusScreen.startStatusDisplay();
        StatusScreen.printStatus("Organizing your movie collection...");
        HttpUtils.initialize();

        processBaseDirFolders();
        processBaseDirFiles();

        HttpUtils.shutdown();
        StatusScreen.printStatus("\nCompleted Successfully !!!");
    }


    /**
     * Processes folders of the base directory
     * @throws ClientProtocolException
     * @throws IOException
     */
    private static void processBaseDirFolders() 
    throws ClientProtocolException, IOException {
        File baseDir = new File(".");
        processDir(baseDir);
    }

    /**
     * Processes the movies with out folders in the base directory
     * @throws ClientProtocolException
     * @throws IOException
     */
    private static void processBaseDirFiles() 
    throws ClientProtocolException, IOException {
        File baseDir = new File(".");
        for (File file : baseDir.listFiles()) {
            if (!file.isDirectory()) {
                processFile(file);
            }
        }
    }

    /**
     * Adds folder to movies with out folders 
     * @param file File
     * @throws ClientProtocolException
     * @throws IOException
     */
    private static void processFile(File file) 
    throws ClientProtocolException, IOException {
        String fileName = file.getName().toLowerCase();
        boolean correctExtension = false;
        for (String extension : movieExtensions) {
            if (fileName.endsWith(extension)) {
                correctExtension = true;
                break;
            }
        }

        if (correctExtension) {
            String[] fileParts = fileName.split("\\.");
            String delimiter = fileParts[fileParts.length - 1];
            File newFile = new File(fileName.split(delimiter)[0]);
            if(newFile.mkdir()) {
                file.renameTo(new File(newFile.getAbsoluteFile().toString() + File.separator + fileName));
                processDir(newFile);
            }
        }
    }


    /**
     * Renames movie directory and adds info file
     * @param directory File
     * @throws ClientProtocolException 
     * @throws IOException  
     */
    private static void processDir(File directory) throws ClientProtocolException, IOException {
        for (File file : directory.listFiles()) {
            if (file.isDirectory()) {
                processDir(file.getAbsoluteFile());
            } 
        }

        if (directory.canWrite()) {
            Movie movie = null;
            File newFileName = null;
            String rawMovieTitle = directory.getName();
            String refinedMovieTitle = getRefinedMovieTitle(rawMovieTitle.toLowerCase());
            try {
                if (refinedMovieTitle == null) {
                    return;
                } 
                movie = new Movie(refinedMovieTitle);
                movie.writeToFile(directory);
                newFileName = movie.getNewFileName();
                if (newFileName != null) {
                    directory.renameTo(newFileName);
                    StatusScreen.printStatus("Lookup & rename complete for " + rawMovieTitle);
                }
            } catch (JSONException e) {
                StatusScreen.printStatus("No film found for: " + rawMovieTitle);
            }
        } else {
            StatusScreen.printStatus(directory.getAbsolutePath() + " is Read Only... not touching it.");
        }
    }

    /**
     * Removes junk characters for the movie title
     * @param title
     * @return
     */
    private static String getRefinedMovieTitle(String title) {
        if (title.charAt(0) == '.' || title.split(Movie.SEPERATOR).length == FILENAME_FILD_COUNT) {
            return null;
        }

        title = title.replace('.', ' ');
        title = title.replace('-', ' ');
        title = title.replace('_', ' ');

        for (String junkStr : junkStrings) {
            int junkStringPosition = title.indexOf(junkStr);
            if (junkStringPosition > 0) {
                title = title.substring(0, junkStringPosition - 1);
            }
        }

        String[] titleWords = title.split(" ");
        for (String word : titleWords) {
            try {
                int year = Integer.parseInt(word);
                if (year >= 1900 && year <= 2050) {
                    int yearPosition = title.indexOf(year + "");
                    if (yearPosition > 0) {
                        title = title.substring(0, yearPosition);
                        return title;
                    }
                }
            }catch(NumberFormatException e) {
                //Do nothing
            }
        }
        
        return title;
    }

}
